1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.io;
18
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static com.google.common.io.SourceSinkFactory.ByteSinkFactory;
21 import static com.google.common.io.SourceSinkFactory.ByteSourceFactory;
22 import static com.google.common.io.SourceSinkFactory.CharSinkFactory;
23 import static com.google.common.io.SourceSinkFactory.CharSourceFactory;
24
25 import com.google.common.base.Charsets;
26
27 import java.io.ByteArrayOutputStream;
28 import java.io.File;
29 import java.io.FileInputStream;
30 import java.io.FileOutputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.InputStreamReader;
34 import java.io.OutputStream;
35 import java.io.OutputStreamWriter;
36 import java.io.Reader;
37 import java.io.Writer;
38 import java.nio.CharBuffer;
39 import java.util.Arrays;
40 import java.util.logging.Logger;
41
42 import javax.annotation.Nullable;
43
44
45
46
47
48
49 public class SourceSinkFactories {
50
51 private SourceSinkFactories() {}
52
53 public static CharSourceFactory stringCharSourceFactory() {
54 return new StringSourceFactory();
55 }
56
57 public static ByteSourceFactory byteArraySourceFactory() {
58 return new ByteArraySourceFactory();
59 }
60
61 public static ByteSourceFactory emptyByteSourceFactory() {
62 return new EmptyByteSourceFactory();
63 }
64
65 public static CharSourceFactory emptyCharSourceFactory() {
66 return new EmptyCharSourceFactory();
67 }
68
69 public static ByteSourceFactory fileByteSourceFactory() {
70 return new FileByteSourceFactory();
71 }
72
73 public static ByteSinkFactory fileByteSinkFactory() {
74 return new FileByteSinkFactory(null);
75 }
76
77 public static ByteSinkFactory appendingFileByteSinkFactory() {
78 String initialString = IoTestCase.ASCII + IoTestCase.I18N;
79 return new FileByteSinkFactory(initialString.getBytes(Charsets.UTF_8));
80 }
81
82 public static CharSourceFactory fileCharSourceFactory() {
83 return new FileCharSourceFactory();
84 }
85
86 public static CharSinkFactory fileCharSinkFactory() {
87 return new FileCharSinkFactory(null);
88 }
89
90 public static CharSinkFactory appendingFileCharSinkFactory() {
91 String initialString = IoTestCase.ASCII + IoTestCase.I18N;
92 return new FileCharSinkFactory(initialString);
93 }
94
95 public static ByteSourceFactory urlByteSourceFactory() {
96 return new UrlByteSourceFactory();
97 }
98
99 public static CharSourceFactory urlCharSourceFactory() {
100 return new UrlCharSourceFactory();
101 }
102
103 public static CharSourceFactory asCharSourceFactory(final ByteSourceFactory factory) {
104 checkNotNull(factory);
105 return new CharSourceFactory() {
106 @Override
107 public CharSource createSource(String string) throws IOException {
108 return factory.createSource(string.getBytes(Charsets.UTF_8))
109 .asCharSource(Charsets.UTF_8);
110 }
111
112 @Override
113 public String getExpected(String data) {
114 return new String(factory.getExpected(data.getBytes(Charsets.UTF_8)), Charsets.UTF_8);
115 }
116
117 @Override
118 public void tearDown() throws IOException {
119 factory.tearDown();
120 }
121 };
122 }
123
124 public static CharSinkFactory asCharSinkFactory(final ByteSinkFactory factory) {
125 checkNotNull(factory);
126 return new CharSinkFactory() {
127 @Override
128 public CharSink createSink() throws IOException {
129 return factory.createSink().asCharSink(Charsets.UTF_8);
130 }
131
132 @Override
133 public String getSinkContents() throws IOException {
134 return new String(factory.getSinkContents(), Charsets.UTF_8);
135 }
136
137 @Override
138 public String getExpected(String data) {
139
140
141
142
143 byte[] factoryExpectedForNothing = factory.getExpected(new byte[0]);
144 return new String(factoryExpectedForNothing, Charsets.UTF_8) + checkNotNull(data);
145 }
146
147 @Override
148 public void tearDown() throws IOException {
149 factory.tearDown();
150 }
151 };
152 }
153
154 public static ByteSourceFactory asSlicedByteSourceFactory(final ByteSourceFactory factory,
155 final int off, final int len) {
156 checkNotNull(factory);
157 return new ByteSourceFactory() {
158 @Override
159 public ByteSource createSource(byte[] bytes) throws IOException {
160 return factory.createSource(bytes).slice(off, len);
161 }
162
163 @Override
164 public byte[] getExpected(byte[] bytes) {
165 byte[] baseExpected = factory.getExpected(bytes);
166 return Arrays.copyOfRange(baseExpected, off, Math.min(baseExpected.length, off + len));
167 }
168
169 @Override
170 public void tearDown() throws IOException {
171 factory.tearDown();
172 }
173 };
174 }
175
176 private static class StringSourceFactory implements CharSourceFactory {
177
178 @Override
179 public CharSource createSource(String data) throws IOException {
180 return CharSource.wrap(data);
181 }
182
183 @Override
184 public String getExpected(String data) {
185 return data;
186 }
187
188 @Override
189 public void tearDown() throws IOException {
190 }
191 }
192
193 private static class ByteArraySourceFactory implements ByteSourceFactory {
194
195 @Override
196 public ByteSource createSource(byte[] bytes) throws IOException {
197 return ByteSource.wrap(bytes);
198 }
199
200 @Override
201 public byte[] getExpected(byte[] bytes) {
202 return bytes;
203 }
204
205 @Override
206 public void tearDown() throws IOException {
207 }
208 }
209
210 private static class EmptyCharSourceFactory implements CharSourceFactory {
211
212 @Override
213 public CharSource createSource(String data) throws IOException {
214 return CharSource.empty();
215 }
216
217 @Override
218 public String getExpected(String data) {
219 return "";
220 }
221
222 @Override
223 public void tearDown() throws IOException {
224 }
225 }
226
227 private static class EmptyByteSourceFactory implements ByteSourceFactory {
228
229 @Override
230 public ByteSource createSource(byte[] bytes) throws IOException {
231 return ByteSource.empty();
232 }
233
234 @Override
235 public byte[] getExpected(byte[] bytes) {
236 return new byte[0];
237 }
238
239 @Override
240 public void tearDown() throws IOException {
241 }
242 }
243
244 private abstract static class FileFactory {
245
246 private static final Logger logger = Logger.getLogger(FileFactory.class.getName());
247
248 private final ThreadLocal<File> fileThreadLocal = new ThreadLocal<File>();
249
250 protected File createFile() throws IOException {
251 File file = File.createTempFile("SinkSourceFile", "txt");
252 fileThreadLocal.set(file);
253 return file;
254 }
255
256 protected File getFile() {
257 return fileThreadLocal.get();
258 }
259
260 public final void tearDown() throws IOException {
261 if (!fileThreadLocal.get().delete()) {
262 logger.warning("Unable to delete file: " + fileThreadLocal.get());
263 }
264 fileThreadLocal.remove();
265 }
266 }
267
268 private static class FileByteSourceFactory extends FileFactory implements ByteSourceFactory {
269
270 @Override
271 public ByteSource createSource(byte[] bytes) throws IOException {
272 checkNotNull(bytes);
273 File file = createFile();
274 OutputStream out = new FileOutputStream(file);
275 try {
276 out.write(bytes);
277 } finally {
278 out.close();
279 }
280 return Files.asByteSource(file);
281 }
282
283 @Override
284 public byte[] getExpected(byte[] bytes) {
285 return checkNotNull(bytes);
286 }
287 }
288
289 private static class FileByteSinkFactory extends FileFactory implements ByteSinkFactory {
290
291 private final byte[] initialBytes;
292
293 private FileByteSinkFactory(@Nullable byte[] initialBytes) {
294 this.initialBytes = initialBytes;
295 }
296
297 @Override
298 public ByteSink createSink() throws IOException {
299 File file = createFile();
300 if (initialBytes != null) {
301 FileOutputStream out = new FileOutputStream(file);
302 try {
303 out.write(initialBytes);
304 } finally {
305 out.close();
306 }
307 return Files.asByteSink(file, FileWriteMode.APPEND);
308 }
309 return Files.asByteSink(file);
310 }
311
312 @Override
313 public byte[] getExpected(byte[] bytes) {
314 if (initialBytes == null) {
315 return checkNotNull(bytes);
316 } else {
317 byte[] result = new byte[initialBytes.length + bytes.length];
318 System.arraycopy(initialBytes, 0, result, 0, initialBytes.length);
319 System.arraycopy(bytes, 0, result, initialBytes.length, bytes.length);
320 return result;
321 }
322 }
323
324 @Override
325 public byte[] getSinkContents() throws IOException {
326 File file = getFile();
327 InputStream in = new FileInputStream(file);
328 ByteArrayOutputStream out = new ByteArrayOutputStream();
329 byte[] buffer = new byte[100];
330 int read;
331 while ((read = in.read(buffer)) != -1) {
332 out.write(buffer, 0, read);
333 }
334 return out.toByteArray();
335 }
336 }
337
338 private static class FileCharSourceFactory extends FileFactory implements CharSourceFactory {
339
340 @Override
341 public CharSource createSource(String string) throws IOException {
342 checkNotNull(string);
343 File file = createFile();
344 Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);
345 try {
346 writer.write(string);
347 } finally {
348 writer.close();
349 }
350 return Files.asCharSource(file, Charsets.UTF_8);
351 }
352
353 @Override
354 public String getExpected(String string) {
355 return checkNotNull(string);
356 }
357 }
358
359 private static class FileCharSinkFactory extends FileFactory implements CharSinkFactory {
360
361 private final String initialString;
362
363 private FileCharSinkFactory(@Nullable String initialString) {
364 this.initialString = initialString;
365 }
366
367 @Override
368 public CharSink createSink() throws IOException {
369 File file = createFile();
370 if (initialString != null) {
371 Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);
372 try {
373 writer.write(initialString);
374 } finally {
375 writer.close();
376 }
377 return Files.asCharSink(file, Charsets.UTF_8, FileWriteMode.APPEND);
378 }
379 return Files.asCharSink(file, Charsets.UTF_8);
380 }
381
382 @Override
383 public String getExpected(String string) {
384 checkNotNull(string);
385 return initialString == null
386 ? string
387 : initialString + string;
388 }
389
390 @Override
391 public String getSinkContents() throws IOException {
392 File file = getFile();
393 Reader reader = new InputStreamReader(new FileInputStream(file), Charsets.UTF_8);
394 StringBuilder builder = new StringBuilder();
395 CharBuffer buffer = CharBuffer.allocate(100);
396 while (reader.read(buffer) != -1) {
397 buffer.flip();
398 builder.append(buffer);
399 buffer.clear();
400 }
401 return builder.toString();
402 }
403 }
404
405 private static class UrlByteSourceFactory extends FileByteSourceFactory {
406
407 @Override
408 public ByteSource createSource(byte[] bytes) throws IOException {
409 super.createSource(bytes);
410 return Resources.asByteSource(getFile().toURI().toURL());
411 }
412 }
413
414 private static class UrlCharSourceFactory extends FileCharSourceFactory {
415
416 @Override
417 public CharSource createSource(String string) throws IOException {
418 super.createSource(string);
419 return Resources.asCharSource(getFile().toURI().toURL(), Charsets.UTF_8);
420 }
421 }
422 }